Tableaux et matrices

La définition de tableaux i.e. vecteurs, matrices, hypermatrices est un élément essentiel du Julia.

Julia ne possède qu'un seul type de tableau : Array on peut définir sont nombre d'entrées (1 entrée= 1 dimension ...) et sont contenu de façon assez générale (Un tableau peut contenir des matrices à chaque élément...

Une particularité est que les indices de tableaux commencent à 1, et l'acces aux éléments se fera à l'aide de '[' ’]' et non '(' ')' qui est réservé aux fonctions.

Avant de rentrer dans la construction et manipulation de tabelau regardons une autre classe

Iterateur

Julia possède un Type particulier fait à l'aide du ":"


In [1]:
a=1:5


Out[1]:
1:5

In [2]:
typeof(a)


Out[2]:
UnitRange{Int64} (constructor with 1 method)

In [3]:
b=0:0.5:2


Out[3]:
0.0:0.5:2.0

In [4]:
typeof(b)


Out[4]:
FloatRange{Float64} (constructor with 1 method)

In [5]:
c=0:1//3:3


Out[5]:
0//1:1//3:3//1

In [6]:
typeof(c)


Out[6]:
StepRange{Rational{Int64},Rational{Int64}} (constructor with 1 method)

Ce type "formel" permet d'avoir une définition et une méthode associée sans stocker l'ensemble des valeurs. Attention celui-ci peut être vide :


In [7]:
d=1:0 # itérateur formel mais correspond à un ensemble vide de valeurs


Out[7]:
1:0

In [8]:
d=[d]


Out[8]:
0-element Array{Int64,1}

Tableau

On vient de voir que l'on peut transformer l'itérateur précédent en tableau à l'aide de "[ ]"


In [9]:
a=1:5
aa=[a]


Out[9]:
5-element Array{Int64,1}:
 1
 2
 3
 4
 5

In [10]:
typeof(aa)


Out[10]:
Array{Int64,1}

La réponse est de la forme Array{Type,dim} un tableau de Type à dim entrées (1 pour vecteur, 2 pour matrices ...)

A remarquer :

  • l'indexation des tableaux commence à 1.
  • un tableau à une entrée est vu comme un vecteur colonne par défaut.
  • le crochet [ ] sert à extraire ou affecter une valeur ou un bloc de valeur. Attention le crochet [ ] sert également de "concatenateur" et constructeur de tableau (voir suite)

In [11]:
aa[1]


Out[11]:
1

In [12]:
aa[end] # pour accèder au dernier élément


Out[12]:
5

In [13]:
aa[end-2:end]=1; println(aa)


[1,2,1,1,1]

Les crochets permettent la construction explicite de tableaux (ou leur concaténation)


In [14]:
A=[1 2 ; 3 4] # {espace} = séparateur de colonne {"," ou ";"} = séparateur de ligne


Out[14]:
2x2 Array{Int64,2}:
 1  2
 3  4

In [15]:
AA=[A  A] # concaténation par block


Out[15]:
2x4 Array{Int64,2}:
 1  2  1  2
 3  4  3  4

In [16]:
AA=[A , A]


Out[16]:
4x2 Array{Int64,2}:
 1  2
 3  4
 1  2
 3  4

In [17]:
AA=[A ; A]


Out[17]:
4x2 Array{Int64,2}:
 1  2
 3  4
 1  2
 3  4

On peut accéder à tout ou partie d'un tableau à l'aide de 2 indices


In [18]:
A[2,1]


Out[18]:
3

In [19]:
A[2,:]


Out[19]:
1x2 Array{Int64,2}:
 3  4

In [20]:
A[end,end]


Out[20]:
4

In [21]:
B=[1,2,3,4]


Out[21]:
4-element Array{Int64,1}:
 1
 2
 3
 4

In [22]:
B=[1;2;3;4]


Out[22]:
4-element Array{Int64,1}:
 1
 2
 3
 4

A noter que l'on peut faire des tableaux de tout type voir de les mélanger (Any)


In [23]:
a=["un";"deux"]


Out[23]:
2-element Array{ASCIIString,1}:
 "un"  
 "deux"

In [24]:
b=[1>2,true,false]


Out[24]:
3-element Array{Bool,1}:
 false
  true
 false

In [25]:
c=["un"; 2 ; true]


Out[25]:
3-element Array{Any,1}:
     "un"
    2    
 true    

Le crochet [ ] permet également la construction rapide de matrice ou tableau comme le montre l'exemple si dessous pour construire une matrice de VanderMonde

$$ V_{i,j}=x_i^{j-1}$$

In [26]:
x=0:0.2:1;
V=[ x[i]^(j-1) for i=1:6, j=1:6] # ligne et colonne


Out[26]:
6x6 Array{Any,2}:
 1.0  0.0  0.0   0.0    0.0     0.0    
 1.0  0.2  0.04  0.008  0.0016  0.00032
 1.0  0.4  0.16  0.064  0.0256  0.01024
 1.0  0.6  0.36  0.216  0.1296  0.07776
 1.0  0.8  0.64  0.512  0.4096  0.32768
 1.0  1.0  1.0   1.0    1.0     1.0    

In [27]:
D=[ u*v for u=1:0.5:3, v=1:0.5:4]


Out[27]:
5x7 Array{Float64,2}:
 1.0  1.5   2.0  2.5   3.0   3.5    4.0
 1.5  2.25  3.0  3.75  4.5   5.25   6.0
 2.0  3.0   4.0  5.0   6.0   7.0    8.0
 2.5  3.75  5.0  6.25  7.5   8.75  10.0
 3.0  4.5   6.0  7.5   9.0  10.5   12.0

Algèbre linéaire

On retrouve beaucoup (toutes) de fonctions usuelles de l'algèbre linéaire


In [28]:
size(A)


Out[28]:
(2,2)

In [29]:
det(A)


Out[29]:
-2.0

In [30]:
trace(A)


Out[30]:
5

In [31]:
eigvals(A)


Out[31]:
2-element Array{Float64,1}:
 -0.372281
  5.37228 

In [32]:
A=[1 2;3 4];b=[2 ; 3]; #résolution du système Ax=b
x=A\b


Out[32]:
2-element Array{Float64,1}:
 -1.0
  1.5

Fonctions scientifiques et opérations

L'usage des fonction scientifiques se fait termes à termes pour l'ensemble des valeurs du tableau (sauf pour les fonctions matricielles comme expm, logm ...). L'usage des opérations +,-,*</code>,^,/ et \(résolution) est disponible à condition de respecter les contraintes de dimension (multiplication matricielle par exemple). Sont ajouté des opérations termes à termes .\*,.^,./ et .\ toujours avec une contrainte de dimensions compatibles.


In [33]:
exp(A)


Out[33]:
2x2 Array{Float64,2}:
  2.71828   7.38906
 20.0855   54.5982 

In [34]:
expm(A) # expoentielle matricielle


Out[34]:
2x2 Array{Float64,2}:
  51.969   74.7366
 112.105  164.074 

De plus les tableaux possèdes des opérations de multiplication, division, puissance termes à termes


In [35]:
A^2 #Multiplication Matricielle


Out[35]:
2x2 Array{Int64,2}:
  7  10
 15  22

In [36]:
A.^2 #Multiplication terme à terme


Out[36]:
2x2 Array{Int64,2}:
 1   4
 9  16

In [37]:
A.//[2 3 ; 4 5] #Division terme à terme ici en fraction rationnelles


Out[37]:
2x2 Array{Rational{Int64},2}:
 1//2  2//3
 3//4  4//5

Constructeurs

Enfin il est possible de construire rapidement certaines matrices


In [38]:
a=linspace(0,1,3) #linspace(début,fin,nombre_éléments)


Out[38]:
3-element Array{Float64,1}:
 0.0
 0.5
 1.0

In [39]:
A=ones(3)


Out[39]:
3-element Array{Float64,1}:
 1.0
 1.0
 1.0

In [40]:
B=randn(5) # loi normale centrée de variance 1


Out[40]:
5-element Array{Float64,1}:
 -2.03907 
 -1.00185 
 -0.339914
 -1.38065 
 -0.335552

In [41]:
B=[ones(3,2) zeros(3,2)] # concaténation de tableaux


Out[41]:
3x4 Array{Float64,2}:
 1.0  1.0  0.0  0.0
 1.0  1.0  0.0  0.0
 1.0  1.0  0.0  0.0

In [42]:
B=[ones(3,2), zeros(3,2)] # , ou ; jouent le rôle de retour à la ligne


Out[42]:
6x2 Array{Float64,2}:
 1.0  1.0
 1.0  1.0
 1.0  1.0
 0.0  0.0
 0.0  0.0
 0.0  0.0

In [43]:
C=eye(3,3)


Out[43]:
3x3 Array{Float64,2}:
 1.0  0.0  0.0
 0.0  1.0  0.0
 0.0  0.0  1.0

In [44]:
diagm(1:4)+diagm(5:7,1) # diagm à partir d'un vecteur cré une matrice


Out[44]:
4x4 Array{Int64,2}:
 1  5  0  0
 0  2  6  0
 0  0  3  7
 0  0  0  4

In [45]:
diag(C) # extraction d'une diagonale


Out[45]:
3-element Array{Float64,1}:
 1.0
 1.0
 1.0

type sparse

Julia possède un type sparse i.e. des matrices creuses, ces dernières ayant un comportement identique aux matrices elles ne diffèrent que dans leur définition (et leur stockage).


In [46]:
A=spzeros(3,3)


Out[46]:
3x3 sparse matrix with 0 Float64 entries:

In [47]:
A=spdiagm(1:3)


Out[47]:
3x3 sparse matrix with 3 Int64 entries:
	[1, 1]  =  1
	[2, 2]  =  2
	[3, 3]  =  3

In [48]:
A=A+spdiagm(1:2,1,3,3)


Out[48]:
3x3 sparse matrix with 5 Int64 entries:
	[1, 1]  =  1
	[1, 2]  =  1
	[2, 2]  =  2
	[2, 3]  =  2
	[3, 3]  =  3

In [49]:
full(A) # pour passer à une matrice pleine


Out[49]:
3x3 Array{Int64,2}:
 1  1  0
 0  2  2
 0  0  3

In [50]:
sparse(eye(4,4)) # pour rendre sparse une matrice "full"


Out[50]:
4x4 sparse matrix with 4 Float64 entries:
	[1, 1]  =  1.0
	[2, 2]  =  1.0
	[3, 3]  =  1.0
	[4, 4]  =  1.0

In [51]:
det(A)


Out[51]:
6